﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArchMethodLibrary.Utils;
using YJKArchMethodLibrary.Utils.Generics;

namespace YJKAxisAndEdit
{
	public class GridCreatorByCurve
	{
		public GridCreatorByCurve(ExternalCommandData cmdData, GridType gridType, double extendLength)
		{
			this.m_Revit = cmdData;
			this.m_GridType = gridType;
			this.m_ExtendLength = extendLength;
			this.InitMaxNumber();
		}

		public void CreateGridByCurves(List<Curve> curveList)
		{
			List<GridCreatorByCurve.ArcInfo> list = new List<GridCreatorByCurve.ArcInfo>();
			List<GridCreatorByCurve.LineInfo> list2 = new List<GridCreatorByCurve.LineInfo>();
			foreach (Curve curve in curveList)
			{
				if (curve.GetType() == typeof(Arc))
				{
					Arc arc = curve as Arc;
					XYZ xyz = new XYZ(arc.GetEndPoint(0).X, arc.GetEndPoint(0).Y, 0.0);
					XYZ xyz2 = new XYZ(arc.GetEndPoint(1).X, arc.GetEndPoint(1).Y, 0.0);
					if (arc.Normal.IsAlmostEqualTo(-XYZ.BasisZ))
					{
						XYZ xyz3 = xyz;
						xyz = xyz2;
						xyz2 = xyz3;
					}
					XYZ center = new XYZ(arc.Center.X, arc.Center.Y, 0.0);
					GridCreatorByCurve.ArcInfo item = new GridCreatorByCurve.ArcInfo(center, xyz, xyz2);
					list.Add(item);
				}
				else if (curve.GetType() == typeof(Line))
				{
					Line curve2 = curve as Line;
					XYZ startPoint = new XYZ(curve2.GetEndPoint(0).X, curve2.GetEndPoint(0).Y, 0.0);
					XYZ endPoint = new XYZ(curve2.GetEndPoint(1).X, curve2.GetEndPoint(1).Y, 0.0);
					GridCreatorByCurve.LineInfo item2 = new GridCreatorByCurve.LineInfo(startPoint, endPoint);
					list2.Add(item2);
				}
			}
			List<XYZ> centerList = new List<XYZ>();
			this.CreateGridByArcs(list, ref centerList);
			this.CreateGridByLines(list2, centerList);
		}

		private void InitMaxNumber()
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			this.m_CurrentMaxDigitalGridNumber = AxisNameManager.GetLargestNumber(document).ToString();
			this.m_CurrentMaxCharGridNumber = AxisNameManager.GetLargestAlpha(document).ToString();
		}

		private string AddNewNumberName(bool isDigital)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			string result;
			if (isDigital)
			{
				result = this.m_CurrentMaxDigitalGridNumber;
				this.m_CurrentMaxDigitalGridNumber = AxisNameManager.GetNextLable(this.m_CurrentMaxDigitalGridNumber);
			}
			else
			{
				result = this.m_CurrentMaxCharGridNumber;
				this.m_CurrentMaxCharGridNumber = AxisNameManager.GetNextLable(this.m_CurrentMaxCharGridNumber);
			}
			return result;
		}

		private void CreateGridByArcs(List<GridCreatorByCurve.ArcInfo> arcInfoList, ref List<XYZ> centerList)
		{
			List<List<GridCreatorByCurve.ArcInfo>> list = new List<List<GridCreatorByCurve.ArcInfo>>();
			foreach (GridCreatorByCurve.ArcInfo item in arcInfoList)
			{
				bool flag = false;
				for (int i = 0; i < list.Count; i++)
				{
					if (item.IsParallel(list[i][0]))
					{
						list[i].Add(item);
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					List<GridCreatorByCurve.ArcInfo> list2 = new List<GridCreatorByCurve.ArcInfo>();
					list2.Add(item);
					list.Add(list2);
				}
			}
			for (int j = 0; j < list.Count; j++)
			{
				List<GridCreatorByCurve.ArcInfo> list3 = list[j];
				this.FilteringOverlapArcs(ref list3);
				list3.Sort(new GridCreatorByCurve.DistanceComparerWithArc(list3[0].Center));
				centerList.Add(list3[0].Center);
				list[j] = list3;
			}
			this.AligningArcGrid(ref list);
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			ElementId id = this.m_Revit.Application.ActiveUIDocument.ActiveView.SketchPlane.Id;
			for (int j = 0; j < list.Count; j++)
			{
				List<GridCreatorByCurve.ArcInfo> list4 = list[j];
				foreach (GridCreatorByCurve.ArcInfo arcInfo in list4)
				{
					if (Geometry.IsEqual(this.m_ExtendLength, 0.0))
					{
						XYZ radianPnt = Geometry.CalculatMidPoint(arcInfo.StartPoint, arcInfo.EndPoint, arcInfo.Center, XYZ.BasisZ);
						Arc arc = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(arcInfo.StartPoint, arcInfo.EndPoint, radianPnt);
						Grid grid = this.m_Revit.Application.ActiveUIDocument.Document.YjkNewGrid(arc);
						if (grid != null)
						{
							grid.Name = this.AddNewNumberName(false);
						}
					}
					else
					{
						XYZ xyz = (arcInfo.StartPoint - arcInfo.Center).Normalize() * this.m_ExtendLength;
						xyz = Geometry.RotateTo(xyz, Math.PI*.5, -XYZ.BasisZ);
						Line item2 = YJKLineEx.YJKGetBound(arcInfo.StartPoint + xyz, arcInfo.StartPoint);
						XYZ xyz2 = (arcInfo.EndPoint - arcInfo.Center).Normalize() * this.m_ExtendLength;
						xyz2 = Geometry.RotateTo(xyz2, Math.PI*.5, XYZ.BasisZ);
						Line item3 = YJKLineEx.YJKGetBound(arcInfo.EndPoint, arcInfo.EndPoint + xyz2);
						XYZ radianPnt2 = Geometry.CalculatMidPoint(arcInfo.StartPoint, arcInfo.EndPoint, arcInfo.Center, XYZ.BasisZ);
						Arc item4 = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(arcInfo.StartPoint, arcInfo.EndPoint, radianPnt2);
						CurveLoop curveLoop = CurveLoop.Create(new List<Curve>
						{
							item2,
							item4,
							item3
						});
						ElementId elementId = RevitDocumentExtension.CreateMultiSegmentGrid(document, this.m_GridType.Id, curveLoop, id);
						if (!(null == elementId))
						{
							MultiSegmentGrid multiSegmentGrid = document.GetElement(elementId) as MultiSegmentGrid;
							if (multiSegmentGrid != null)
							{
								multiSegmentGrid.Name = this.AddNewNumberName(false);
							}
						}
					}
				}
			}
		}

		private void CreateGridByLines(List<GridCreatorByCurve.LineInfo> lineInfoList, List<XYZ> centerList)
		{
			List<List<GridCreatorByCurve.LineInfo>> list = new List<List<GridCreatorByCurve.LineInfo>>();
			foreach (GridCreatorByCurve.LineInfo item in lineInfoList)
			{
				bool flag = false;
				for (int i = 0; i < list.Count; i++)
				{
					if (item.IsParallel(list[i][0]))
					{
						list[i].Add(item);
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					List<GridCreatorByCurve.LineInfo> list2 = new List<GridCreatorByCurve.LineInfo>();
					list2.Add(item);
					list.Add(list2);
				}
			}
			for (int j = 0; j < list.Count; j++)
			{
				List<GridCreatorByCurve.LineInfo> list3 = list[j];
				this.FilteringOverlapLines(ref list3);
				list3.Sort(new GridCreatorByCurve.DistanceComparerWithLine(new XYZ(-10000.0, -10000.0, 0.0)));
				list[j] = list3;
			}
			List<List<GridCreatorByCurve.LineInfo>> list4 = new List<List<GridCreatorByCurve.LineInfo>>();
			List<XYZ> list5 = new List<XYZ>();
			for (int j = 0; j < centerList.Count; j++)
			{
				XYZ xyz = centerList[j];
				List<GridCreatorByCurve.LineInfo> list6 = new List<GridCreatorByCurve.LineInfo>();
				for (int k = 0; k < list.Count; k++)
				{
					List<GridCreatorByCurve.LineInfo> list7 = list[k];
					for (int l = 0; l < list7.Count; l++)
					{
						GridCreatorByCurve.LineInfo item2 = list7[l];
						XYZ startPoint = item2.StartPoint;
						XYZ endPoint = item2.EndPoint;
						if (Geometry.Is_Points_Collinear(startPoint, endPoint, xyz, 1E-09))
						{
							list6.Add(item2);
							list7.RemoveAt(l);
							l--;
						}
					}
				}
				if (list6.Count > 0)
				{
					list6.Sort(new GridCreatorByCurve.AngleComparerWithLine(xyz, xyz + XYZ.BasisX * 10.0));
					list4.Add(list6);
					list5.Add(xyz);
				}
			}
			this.AligningParallelGrid(ref list);
			this.AligningSectorGrid(ref list4, list5);
			for (int j = 0; j < list.Count; j++)
			{
				List<GridCreatorByCurve.LineInfo> list8 = list[j];
				foreach (GridCreatorByCurve.LineInfo lineInfo in list8)
				{
					XYZ xyz2 = lineInfo.StartPoint;
					XYZ xyz3 = lineInfo.EndPoint;
					XYZ xyz4 = (xyz3 - xyz2).Normalize();
					XYZ xyz5 = xyz4 * this.m_ExtendLength;
					xyz2 -= xyz5;
					xyz3 += xyz5;
					Line line = YJKLineEx.YJKGetBound(xyz2, xyz3);
					Grid grid = this.m_Revit.Application.ActiveUIDocument.Document.YjkNewGrid(line);
					if (grid != null)
					{
						double val = XYZ.BasisX.AngleTo(xyz4);
						if (Geometry.GreaterThan(val, 0.78539816339744828) && Geometry.Lessthan_Or_Equal(val, 2.3561944901923448))
						{
							grid.Name = this.AddNewNumberName(true);
						}
						else
						{
							grid.Name = this.AddNewNumberName(false);
						}
						if (this.m_GridType != null)
						{
							grid.ChangeTypeId(this.m_GridType.Id);
						}
					}
				}
			}
			for (int j = 0; j < list4.Count; j++)
			{
				List<GridCreatorByCurve.LineInfo> list9 = list4[j];
				foreach (GridCreatorByCurve.LineInfo lineInfo2 in list9)
				{
					XYZ xyz6 = lineInfo2.StartPoint;
					XYZ xyz7 = lineInfo2.EndPoint;
					XYZ xyz8 = (xyz7 - xyz6).Normalize() * this.m_ExtendLength;
					xyz6 -= xyz8;
					xyz7 += xyz8;
					Line line2 = YJKLineEx.YJKGetBound(xyz6, xyz7);
					Grid grid2 = this.m_Revit.Application.ActiveUIDocument.Document.YjkNewGrid(line2);
					if (grid2 != null)
					{
						grid2.Name = this.AddNewNumberName(true);
						if (this.m_GridType != null)
						{
							grid2.ChangeTypeId(this.m_GridType.Id);
						}
					}
				}
			}
		}

		private void AligningArcGrid(ref List<List<GridCreatorByCurve.ArcInfo>> parallelGroupList)
		{
			for (int i = 0; i < parallelGroupList.Count; i++)
			{
				List<GridCreatorByCurve.ArcInfo> list = parallelGroupList[i];
				List<XYZ> list2 = new List<XYZ>();
				List<XYZ> list3 = new List<XYZ>();
				for (int j = 0; j < list.Count; j++)
				{
					GridCreatorByCurve.ArcInfo arcInfo = list[j];
					list2.Add(arcInfo.StartPoint);
					list3.Add(arcInfo.EndPoint);
				}
				XYZ center = list[0].Center;
				list2.Sort(new YJKArchMethodLibrary.Utils.Generics.AngleComparer(list2[0], center));
				list3.Sort(new YJKArchMethodLibrary.Utils.Generics.AngleComparer(list3[0], center));
				XYZ xyz = null;
				XYZ xyz2 = null;
				this.GetMinorArcEnds(list2, center, ref xyz, ref xyz2);
				XYZ xyz3 = (xyz - center).Normalize();
				XYZ xyz4 = null;
				XYZ xyz5 = null;
				this.GetMinorArcEnds(list3, center, ref xyz4, ref xyz5);
				XYZ xyz6 = (xyz5 - center).Normalize();
				for (int j = 0; j < list.Count; j++)
				{
					XYZ center2 = list[j].Center;
					double radius = list[j].Radius;
					XYZ xyz7 = center2 + xyz3 * radius;
					XYZ xyz8 = center2 + xyz6 * radius;
					if (Geometry.IsEqual(xyz7, xyz8, 0.0001))
					{
						parallelGroupList[i].RemoveAt(j);
						j--;
					}
					else
					{
						parallelGroupList[i][j] = new GridCreatorByCurve.ArcInfo(center2, xyz7, xyz8);
					}
				}
			}
		}

		private void GetMinorArcEnds(List<XYZ> pointsOnArc, XYZ center, ref XYZ ptStart, ref XYZ ptEnd)
		{
			if (pointsOnArc.Count == 1)
			{
				ptStart = pointsOnArc[0];
				ptEnd = pointsOnArc[0];
				return;
			}
			double val = 0.0;
			for (int i = 0; i < pointsOnArc.Count; i++)
			{
				XYZ xyz = pointsOnArc[i];
				XYZ xyz2;
				if (i == pointsOnArc.Count - 1)
				{
					xyz2 = pointsOnArc[0];
				}
				else
				{
					xyz2 = pointsOnArc[i + 1];
				}
				double angle = Geometry.getAngle(center, xyz);
				double angle2 = Geometry.getAngle(center, xyz2);
				double num = Geometry.BetweenTheAngles(angle, angle2, true);
				if (Geometry.LessThan(val, num))
				{
					val = num;
					ptStart = xyz2;
					ptEnd = xyz;
				}
			}
			if (ptStart == null || ptEnd == null)
			{
				ptStart = pointsOnArc[0];
				ptEnd = pointsOnArc[0];
			}
		}

		private void AligningSectorGrid(ref List<List<GridCreatorByCurve.LineInfo>> sectorGroupList, List<XYZ> sectorCenterList)
		{
			for (int i = 0; i < sectorGroupList.Count; i++)
			{
				List<GridCreatorByCurve.LineInfo> list = sectorGroupList[i];
				XYZ xyz = sectorCenterList[i];
				double num = double.MaxValue;
				double num2 = 0.0;
				for (int j = 0; j < list.Count; j++)
				{
					GridCreatorByCurve.LineInfo lineInfo = list[j];
					double num3 = lineInfo.StartPoint.DistanceTo(xyz);
					double num4 = lineInfo.EndPoint.DistanceTo(xyz);
					if (Geometry.LessThan(num4, num3))
					{
						double num5 = num3;
						num3 = num4;
						num4 = num5;
					}
					if (Geometry.LessThan(num3, num))
					{
						num = num3;
					}
					if (Geometry.LessThan(num2, num4))
					{
						num2 = num4;
					}
				}
				for (int j = 0; j < list.Count; j++)
				{
					GridCreatorByCurve.LineInfo lineInfo2 = list[j];
					XYZ xyz2 = Geometry.CalculatMidPoint(lineInfo2.StartPoint, lineInfo2.EndPoint);
					XYZ xyz3 = (xyz2 - xyz).Normalize();
					sectorGroupList[i][j] = new GridCreatorByCurve.LineInfo(xyz + xyz3 * num2, xyz + xyz3 * num);
				}
			}
		}

		private void AligningParallelGrid(ref List<List<GridCreatorByCurve.LineInfo>> parallelGroupList)
		{
			for (int i = 0; i < parallelGroupList.Count; i++)
			{
				List<GridCreatorByCurve.LineInfo> list = parallelGroupList[i];
				if (list.Count == 0)
				{
					parallelGroupList.RemoveAt(i);
					i--;
				}
				else
				{
					GridCreatorByCurve.LineInfo lineInfo = list[0];
					List<XYZ> list2 = new List<XYZ>();
					list2.Add(lineInfo.StartPoint);
					list2.Add(lineInfo.EndPoint);
					for (int j = 1; j < list.Count; j++)
					{
						GridCreatorByCurve.LineInfo lineInfo2 = list[j];
						XYZ item = Geometry.CalculateFootPoint(lineInfo.StartPoint, lineInfo.EndPoint, lineInfo2.StartPoint);
						list2.Add(item);
						XYZ item2 = Geometry.CalculateFootPoint(lineInfo.StartPoint, lineInfo.EndPoint, lineInfo2.EndPoint);
						list2.Add(item2);
					}
                    list2.Sort(new YJKRevitCode.RevitObjectCompareUtility.XYComparer());
					XYZ point = list2[0];
					XYZ point2 = list2[list2.Count - 1];
					for (int j = 0; j < list.Count; j++)
					{
						GridCreatorByCurve.LineInfo lineInfo3 = list[j];
						XYZ xyz = Geometry.CalculateFootPoint(lineInfo3.StartPoint, lineInfo3.EndPoint, point);
						list2.Add(xyz);
						XYZ xyz2 = Geometry.CalculateFootPoint(lineInfo3.StartPoint, lineInfo3.EndPoint, point2);
						list2.Add(xyz2);
						parallelGroupList[i][j] = new GridCreatorByCurve.LineInfo(xyz, xyz2);
					}
				}
			}
		}

		private void FilteringOverlapArcs(ref List<GridCreatorByCurve.ArcInfo> arcInfoList)
		{
			double eps = Common.MMToFeet(1.0);
			for (int i = 0; i < arcInfoList.Count; i++)
			{
				for (int j = i + 1; j < arcInfoList.Count; j++)
				{
					double radius = arcInfoList[i].Radius;
					double radius2 = arcInfoList[j].Radius;
					if (Geometry.IsEqual(radius, radius2, eps))
					{
						XYZ startPoint = arcInfoList[i].StartPoint;
						XYZ endPoint = arcInfoList[i].EndPoint;
						XYZ center = arcInfoList[i].Center;
						XYZ startPoint2 = arcInfoList[j].StartPoint;
						XYZ endPoint2 = arcInfoList[j].EndPoint;
						XYZ center2 = arcInfoList[j].Center;
						XYZ startPoint3 = XYZ.Zero;
						XYZ endPoint3 = XYZ.Zero;
						Geometry.OverlapType overlapType = Geometry.MergerOfTwoArc(startPoint, endPoint, center, startPoint2, endPoint2, center2, ref startPoint3, ref endPoint3);
						if (overlapType == Geometry.OverlapType._OT_None)
						{
							double angle = Geometry.getAngle(center, startPoint);
							double angle2 = Geometry.getAngle(center, endPoint);
							double angle3 = Geometry.getAngle(center, startPoint2);
							double angle4 = Geometry.getAngle(center, endPoint2);
							double val = Geometry.BetweenTheAngles(angle2, angle3, true);
							double val2 = Geometry.BetweenTheAngles(angle4, angle, true);
							startPoint3 = startPoint2;
							endPoint3 = endPoint;
							if (Geometry.LessThan(val, val2))
							{
								startPoint3 = startPoint;
								endPoint3 = endPoint2;
							}
							arcInfoList[i] = new GridCreatorByCurve.ArcInfo(center, startPoint3, endPoint3);
							arcInfoList.RemoveAt(j);
							j--;
						}
						else if (overlapType == Geometry.OverlapType._OT_Equality || overlapType == Geometry.OverlapType._OT_FirstIncludeSecond)
						{
							arcInfoList.RemoveAt(j);
							j--;
						}
						else if (overlapType == Geometry.OverlapType._OT_SecondIncludeFirst || overlapType == Geometry.OverlapType._OT_Part || overlapType == Geometry.OverlapType._OT_Linked)
						{
							arcInfoList[i] = new GridCreatorByCurve.ArcInfo(center, startPoint3, endPoint3);
							arcInfoList.RemoveAt(j);
							j--;
						}
					}
				}
			}
		}

		private void FilteringOverlapLines(ref List<GridCreatorByCurve.LineInfo> lineInfoList)
		{
			for (int i = 0; i < lineInfoList.Count; i++)
			{
				for (int j = i + 1; j < lineInfoList.Count; j++)
				{
					XYZ startPoint = lineInfoList[i].StartPoint;
					XYZ endPoint = lineInfoList[i].EndPoint;
					XYZ startPoint2 = lineInfoList[j].StartPoint;
					XYZ endPoint2 = lineInfoList[j].EndPoint;
					if (Geometry.Is_Points_Collinear(startPoint, endPoint, startPoint2, 1E-09))
					{
						List<XYZ> list = new List<XYZ>();
						list.Add(startPoint);
						list.Add(endPoint);
						list.Add(startPoint2);
						list.Add(endPoint2);
                        list.Sort(new YJKRevitCode.RevitObjectCompareUtility.XYComparer());
						lineInfoList[i] = new GridCreatorByCurve.LineInfo(list[0], list[list.Count - 1]);
						lineInfoList.RemoveAt(j);
						j--;
					}
				}
			}
		}

		private ExternalCommandData m_Revit;

		private GridType m_GridType;

		private double m_ExtendLength;

		private string m_CurrentMaxDigitalGridNumber = "";

		private string m_CurrentMaxCharGridNumber = "";

		public struct ArcInfo
		{
			public XYZ StartPoint
			{
				get
				{
					return this.m_ptStart;
				}
				set
				{
					this.m_ptStart = value;
				}
			}

			public XYZ EndPoint
			{
				get
				{
					return this.m_ptEnd;
				}
				set
				{
					this.m_ptEnd = value;
				}
			}

			public XYZ Center
			{
				get
				{
					return this.m_ptCenter;
				}
				set
				{
					this.m_ptCenter = value;
				}
			}

			public double Radius
			{
				get
				{
					return this.Center.DistanceTo(this.m_ptStart);
				}
			}

			public ArcInfo(GridCreatorByCurve.ArcInfo rhs)
			{
				this.m_ptCenter = rhs.m_ptCenter;
				this.m_ptStart = rhs.m_ptStart;
				this.m_ptEnd = rhs.m_ptEnd;
			}

			public ArcInfo(XYZ center, XYZ startPoint, XYZ endPoint)
			{
				this.m_ptCenter = center;
				this.m_ptStart = startPoint;
				this.m_ptEnd = endPoint;
			}

			public bool IsParallel(GridCreatorByCurve.ArcInfo arcInfo)
			{
				return Geometry.IsEqual(this.Center.X, arcInfo.Center.X, 0.0001) && Geometry.IsEqual(this.Center.Y, arcInfo.Center.Y, 0.0001) && Geometry.IsEqual(this.Center.Z, arcInfo.Center.Z, 0.0001);
			}

			private XYZ m_ptCenter;

			private XYZ m_ptStart;

			private XYZ m_ptEnd;
		}

		public struct LineInfo
		{
			public XYZ StartPoint
			{
				get
				{
					return this.m_ptStart;
				}
				set
				{
					this.m_ptStart = value;
				}
			}

			public XYZ EndPoint
			{
				get
				{
					return this.m_ptEnd;
				}
				set
				{
					this.m_ptEnd = value;
				}
			}

			public LineInfo(GridCreatorByCurve.LineInfo rhs)
			{
				this.m_ptStart = rhs.m_ptStart;
				this.m_ptEnd = rhs.m_ptEnd;
			}

			public LineInfo(XYZ startPoint, XYZ endPoint)
			{
				this.m_ptStart = startPoint;
				this.m_ptEnd = endPoint;
			}

			public bool IsParallel(GridCreatorByCurve.LineInfo lineInfo)
			{
				XYZ a = (this.EndPoint - this.StartPoint).Normalize();
				XYZ xyz = (lineInfo.EndPoint - lineInfo.StartPoint).Normalize();
				return Geometry.IsParallel(a, xyz, 1E-09) || Geometry.IsParallel(a, -xyz, 1E-09);
			}

			private XYZ m_ptStart;

			private XYZ m_ptEnd;
		}

		public class DistanceComparerWithArc : IComparer<GridCreatorByCurve.ArcInfo>
		{
			public DistanceComparerWithArc(XYZ refPoint)
			{
				this.m_ReferencePoint = refPoint;
			}

			public int Compare(GridCreatorByCurve.ArcInfo arcInfo1, GridCreatorByCurve.ArcInfo arcInfo2)
			{
				XYZ startPoint = arcInfo1.StartPoint;
				XYZ startPoint2 = arcInfo2.StartPoint;
				return startPoint.DistanceTo(this.m_ReferencePoint).CompareTo(startPoint2.DistanceTo(this.m_ReferencePoint));
			}

			private XYZ m_ReferencePoint;
		}

		public class DistanceComparerWithLine : IComparer<GridCreatorByCurve.LineInfo>
		{
			public DistanceComparerWithLine(XYZ refPoint)
			{
				this.m_ReferencePoint = refPoint;
			}

			public int Compare(GridCreatorByCurve.LineInfo lineInfo1, GridCreatorByCurve.LineInfo lineInfo2)
			{
				XYZ xyz = Geometry.CalculateFootPoint(lineInfo1.StartPoint, lineInfo1.EndPoint, this.m_ReferencePoint);
				XYZ xyz2 = Geometry.CalculateFootPoint(lineInfo2.StartPoint, lineInfo2.EndPoint, this.m_ReferencePoint);
				return xyz.DistanceTo(this.m_ReferencePoint).CompareTo(xyz2.DistanceTo(this.m_ReferencePoint));
			}

			private XYZ m_ReferencePoint;
		}

		public class AngleComparerWithLine : IComparer<GridCreatorByCurve.LineInfo>
		{
			public AngleComparerWithLine(XYZ center, XYZ refPoint)
			{
				this.m_ReferencePoint = refPoint;
				this.m_Center = center;
			}

			public int Compare(GridCreatorByCurve.LineInfo lineInfo1, GridCreatorByCurve.LineInfo lineInfo2)
			{
				XYZ xyz = this.m_ReferencePoint - this.m_Center;
				XYZ xyz2 = Geometry.CalculatMidPoint(lineInfo1.StartPoint, lineInfo1.EndPoint) - this.m_Center;
				XYZ xyz3 = Geometry.CalculatMidPoint(lineInfo2.StartPoint, lineInfo2.EndPoint) - this.m_Center;
				double num = xyz.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
				if (Math.Abs(num - Math.PI*2) < 1E-06)
				{
					num = 0.0;
				}
				double num2 = xyz.AngleOnPlaneTo(xyz3, XYZ.BasisZ);
				if (Math.Abs(num2 - Math.PI*2) < 1E-06)
				{
					num2 = 0.0;
				}
				return num.CompareTo(num2);
			}

			private XYZ m_ReferencePoint;

			private XYZ m_Center;
		}
	}
}
